home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Blender 2.49b / blender-2.49b-windows.exe / $_4_ / .blender / scripts / bpymodules / meshtools.py < prev    next >
Text File  |  2009-08-31  |  13KB  |  356 lines

  1. # $Id: meshtools.py 9294 2006-12-12 10:38:43Z campbellbarton $
  2. #
  3. # +---------------------------------------------------------+
  4. # | Copyright (c) 2001 Anthony D'Agostino                   |
  5. # | http://www.redrival.com/scorpius                        |
  6. # | scorpius@netzero.com                                    |
  7. # | September 28, 2002                                      |
  8. # +---------------------------------------------------------+
  9. # | Common Functions & Global Variables For All IO Modules  |
  10. # +---------------------------------------------------------+
  11.  
  12. # ***** BEGIN GPL LICENSE BLOCK *****
  13. #
  14. # This program is free software; you can redistribute it and/or
  15. # modify it under the terms of the GNU General Public License
  16. # as published by the Free Software Foundation; either version 2
  17. # of the License, or (at your option) any later version.
  18. #
  19. # This program is distributed in the hope that it will be useful,
  20. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22. # GNU General Public License for more details.
  23. #
  24. # You should have received a copy of the GNU General Public License
  25. # along with this program; if not, write to the Free Software Foundation,
  26. # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  27. #
  28. # ***** END GPL LICENCE BLOCK *****
  29.  
  30. import Blender
  31. import sys
  32.  
  33. show_progress = 1            # Set to 0 for faster performance
  34. average_vcols = 1            # Off for per-face, On for per-vertex
  35. overwrite_mesh_name = 0     # Set to 0 to increment object-name version
  36.  
  37. blender_version = Blender.Get('version')
  38. blender_version_str = `blender_version`[0] + '.' + `blender_version`[1:]
  39.  
  40. try:
  41.     import operator
  42. except:
  43.     msg = "Error: you need a full Python install to run this script."
  44.     meshtools.print_boxed(msg)
  45.     Blender.Draw.PupMenu("ERROR%t|"+msg)
  46.  
  47. # =================================
  48. # === Append Faces To Face List ===
  49. # =================================
  50. def append_faces(mesh, faces, facesuv, uvcoords):
  51.     for i in xrange(len(faces)):
  52.         if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(faces), "Generating Faces")
  53.         numfaceverts=len(faces[i])
  54.         if numfaceverts == 2: #This is not a face is an edge
  55.             if mesh.edges == None:  #first run
  56.                 mesh.addEdgeData()
  57.             #rev_face = revert(cur_face)
  58.             i1 = faces[i][0]
  59.             i2 = faces[i][1]
  60.             ee = mesh.addEdge(mesh.verts[i1],mesh.verts[i2])
  61.             ee.flag |= Blender.NMesh.EdgeFlags.EDGEDRAW
  62.             ee.flag |= Blender.NMesh.EdgeFlags.EDGERENDER
  63.         elif numfaceverts in [3,4]:                # This face is a triangle or quad
  64.             face = Blender.NMesh.Face()
  65.             for j in xrange(numfaceverts):
  66.                 index = faces[i][j]
  67.                 face.v.append(mesh.verts[index])
  68.                 if len(uvcoords) > 1:
  69.                     uvidx = facesuv[i][j]
  70.                     face.uv.append(uvcoords[uvidx])
  71.                     face.mode = 0
  72.                     face.col = [Blender.NMesh.Col()]*4
  73.             mesh.faces.append(face)
  74.         else:                                # Triangulate n-sided convex polygon.
  75.             a, b, c = 0, 1, 2                # Indices of first triangle.
  76.             for j in xrange(numfaceverts-2): # Number of triangles in polygon.
  77.                 face = Blender.NMesh.Face()
  78.                 face.v.append(mesh.verts[faces[i][a]])
  79.                 face.v.append(mesh.verts[faces[i][b]])
  80.                 face.v.append(mesh.verts[faces[i][c]])
  81.                 b = c; c += 1
  82.                 mesh.faces.append(face)
  83.         #face.smooth = 1
  84.  
  85. # ===================================
  86. # === Append Verts to Vertex List ===
  87. # ===================================
  88. def append_verts(mesh, verts, normals):
  89.     #print "Number of normals:", len(normals)
  90.     #print "Number of verts  :", len(verts)
  91.     for i in xrange(len(verts)):
  92.         if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(verts), "Generating Verts")
  93.         x, y, z = verts[i]
  94.         mesh.verts.append(Blender.NMesh.Vert(x, y, z))
  95.         if normals:
  96.             mesh.verts[i].no[0] = normals[i][0]
  97.             mesh.verts[i].no[1] = normals[i][1]
  98.             mesh.verts[i].no[2] = normals[i][2]
  99.  
  100. # ===========================
  101. # === Create Blender Mesh ===
  102. # ===========================
  103. def create_mesh(verts, faces, objname, facesuv=[], uvcoords=[], normals=[]):
  104.     if normals: normal_flag = 0
  105.     else: normal_flag = 1
  106.     mesh = Blender.NMesh.GetRaw()
  107.     append_verts(mesh, verts, normals)
  108.     append_faces(mesh, faces, facesuv, uvcoords)
  109.     if not overwrite_mesh_name:
  110.         objname = versioned_name(objname)
  111.     ob= Blender.NMesh.PutRaw(mesh, objname, normal_flag)    # Name the Mesh
  112.     ob.name= objname        # Name the Object
  113.     Blender.Redraw()
  114.  
  115. # ==============================
  116. # === Increment Name Version ===
  117. # ==============================
  118. def versioned_name(objname):
  119.     existing_names = []
  120.     for object in Blender.Object.Get():
  121.         existing_names.append(object.name)
  122.         existing_names.append(object.getData(name_only=1))
  123.     if objname in existing_names: # don't over-write other names
  124.         try:
  125.             name, ext = objname.split('.')
  126.         except ValueError:
  127.             name, ext = objname, ''
  128.         try:
  129.             num = int(ext)
  130.             root = name
  131.         except ValueError:
  132.             root = objname
  133.         for i in xrange(1, 1000):
  134.             objname = "%s.%03d" % (root, i)
  135.             if objname not in existing_names:
  136.                 break
  137.     return objname
  138.  
  139. # ===========================
  140. # === Print Text In A Box ===
  141. # ===========================
  142. def print_boxed(text):
  143.     lines = text.splitlines()
  144.     maxlinelen = max(map(len, lines))
  145.     if sys.platform[:3] == "win":
  146.         print chr(218)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(191)
  147.         for line in lines:
  148.             print chr(179) + ' ' + line.ljust(maxlinelen) + ' ' + chr(179)
  149.         print chr(192)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(217)
  150.     else:
  151.         print '+-' + '-'*maxlinelen + '-+'
  152.         for line in lines: print '| ' + line.ljust(maxlinelen) + ' |'
  153.         print '+-' + '-'*maxlinelen + '-+'
  154.     print '\a\r', # beep when done
  155.  
  156. # ===============================================
  157. # === Get euler angles from a rotation matrix ===
  158. # ===============================================
  159. def mat2euler(mat):
  160.     angle_y = -math.asin(mat[0][2])
  161.     c = math.cos(angle_y)
  162.     if math.fabs(c) > 0.005:
  163.         angle_x = math.atan2(mat[1][2]/c, mat[2][2]/c)
  164.         angle_z = math.atan2(mat[0][1]/c, mat[0][0]/c)
  165.     else:
  166.         angle_x = 0.0
  167.         angle_z = -math.atan2(mat[1][0], mat[1][1])
  168.     return (angle_x, angle_y, angle_z)
  169.  
  170. # ==========================
  171. # === Transpose A Matrix ===
  172. # ==========================
  173. def transpose(A):
  174.     S = len(A)
  175.     T = len(A[0])
  176.     B = [[None]*S for i in xrange(T)]
  177.     for i in xrange(T):
  178.         for j in xrange(S):
  179.             B[i][j] = A[j][i]
  180.     return B
  181.  
  182. # =======================
  183. # === Apply Transform ===
  184. # =======================
  185. def apply_transform(vertex, matrix):
  186.     x, y, z = vertex
  187.     xloc, yloc, zloc = matrix[3][0], matrix[3][1], matrix[3][2]
  188.     xcomponent = x*matrix[0][0] + y*matrix[1][0] + z*matrix[2][0] + xloc
  189.     ycomponent = x*matrix[0][1] + y*matrix[1][1] + z*matrix[2][1] + yloc
  190.     zcomponent = x*matrix[0][2] + y*matrix[1][2] + z*matrix[2][2] + zloc
  191.     vertex = [xcomponent, ycomponent, zcomponent]
  192.     return vertex
  193.  
  194. # =========================
  195. # === Has Vertex Colors ===
  196. # =========================
  197. def has_vertex_colors(mesh):
  198.     # My replacement/workaround for hasVertexColours()
  199.     # The docs say:
  200.     # "Warning: If a mesh has both vertex colours and textured faces,
  201.     # this function will return False. This is due to the way Blender
  202.     # deals internally with the vertex colours array (if there are
  203.     # textured faces, it is copied to the textured face structure and
  204.     # the original array is freed/deleted)."
  205.     try:
  206.         return mesh.faces[0].col[0]
  207.     except:
  208.         return 0
  209.  
  210. # ===========================
  211. # === Generate Edge Table ===
  212. # ===========================
  213. def generate_edgetable(mesh):
  214.     edge_table = {}
  215.     numfaces = len(mesh.faces)
  216.  
  217.     for i in xrange(numfaces):
  218.         if not i%100 and show_progress:
  219.             Blender.Window.DrawProgressBar(float(i)/numfaces, "Generating Edge Table")
  220.         if len(mesh.faces[i].v) == 4:    # Process Quadrilaterals
  221.             generate_entry_from_quad(mesh, i, edge_table)
  222.         elif len(mesh.faces[i].v) == 3: # Process Triangles
  223.             generate_entry_from_tri(mesh, i, edge_table)
  224.         else:                            # Skip This Face
  225.             print "Face #", i, "was skipped."
  226.  
  227.     # === Sort Edge_Table Keys & Add Edge Indices ===
  228.     i = 0
  229.     keys = edge_table.keys()
  230.     keys.sort()
  231.     for key in keys:
  232.         edge_table[key][6] = i
  233.         i += 1
  234.  
  235.     # === Replace Tuples With Indices ===
  236.     for key in keys:
  237.         for i in [2,3,4,5]:
  238.             if edge_table.has_key(edge_table[key][i]):
  239.                 edge_table[key][i] = edge_table[edge_table[key][i]][6]
  240.             else:
  241.                 keyrev = (edge_table[key][i][1], edge_table[key][i][0])
  242.                 edge_table[key][i] = edge_table[keyrev][6]
  243.  
  244.     return edge_table
  245.  
  246. # ================================
  247. # === Generate Entry From Quad ===
  248. # ================================
  249. def generate_entry_from_quad(mesh, i, edge_table):
  250.     vertex4, vertex3, vertex2, vertex1 = mesh.faces[i].v
  251.  
  252.     if has_vertex_colors(mesh):
  253.         vcolor4, vcolor3, vcolor2, vcolor1 = mesh.faces[i].col
  254.         Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0)
  255.         Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0)
  256.         Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0)
  257.         Dcol = (vcolor4.r/255.0, vcolor4.g/255.0, vcolor4.b/255.0)
  258.  
  259.     # === verts are upper case, edges are lower case ===
  260.     A, B, C, D = vertex1.index, vertex2.index, vertex3.index, vertex4.index
  261.     a, b, c, d = (A, B), (B, C), (C, D), (D, A)
  262.  
  263.     if edge_table.has_key((B, A)):
  264.         edge_table[(B, A)][1] = i
  265.         edge_table[(B, A)][4] = d
  266.         edge_table[(B, A)][5] = b
  267.         if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol
  268.     else:
  269.         if has_vertex_colors(mesh):
  270.             edge_table[(A, B)] = [i, None, d, b, None, None, None, Bcol, None]
  271.         else:
  272.             edge_table[(A, B)] = [i, None, d, b, None, None, None]
  273.  
  274.     if edge_table.has_key((C, B)):
  275.         edge_table[(C, B)][1] = i
  276.         edge_table[(C, B)][4] = a
  277.         edge_table[(C, B)][5] = c
  278.         if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol
  279.     else:
  280.         if has_vertex_colors(mesh):
  281.             edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None]
  282.         else:
  283.             edge_table[(B, C)] = [i, None, a, c, None, None, None]
  284.  
  285.     if edge_table.has_key((D, C)):
  286.         edge_table[(D, C)][1] = i
  287.         edge_table[(D, C)][4] = b
  288.         edge_table[(D, C)][5] = d
  289.         if has_vertex_colors(mesh): edge_table[(D, C)][8] = Dcol
  290.     else:
  291.         if has_vertex_colors(mesh):
  292.             edge_table[(C, D)] = [i, None, b, d, None, None, None, Dcol, None]
  293.         else:
  294.             edge_table[(C, D)] = [i, None, b, d, None, None, None]
  295.  
  296.     if edge_table.has_key((A, D)):
  297.         edge_table[(A, D)][1] = i
  298.         edge_table[(A, D)][4] = c
  299.         edge_table[(A, D)][5] = a
  300.         if has_vertex_colors(mesh): edge_table[(A, D)][8] = Acol
  301.     else:
  302.         if has_vertex_colors(mesh):
  303.             edge_table[(D, A)] = [i, None, c, a, None, None, None, Acol, None]
  304.         else:
  305.             edge_table[(D, A)] = [i, None, c, a, None, None, None]
  306.  
  307. # ====================================
  308. # === Generate Entry From Triangle ===
  309. # ====================================
  310. def generate_entry_from_tri(mesh, i, edge_table):
  311.     vertex3, vertex2, vertex1 = mesh.faces[i].v
  312.  
  313.     if has_vertex_colors(mesh):
  314.         vcolor3, vcolor2, vcolor1, _vcolor4_ = mesh.faces[i].col
  315.         Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0)
  316.         Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0)
  317.         Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0)
  318.  
  319.     # === verts are upper case, edges are lower case ===
  320.     A, B, C = vertex1.index, vertex2.index, vertex3.index
  321.     a, b, c = (A, B), (B, C), (C, A)
  322.  
  323.     if edge_table.has_key((B, A)):
  324.         edge_table[(B, A)][1] = i
  325.         edge_table[(B, A)][4] = c
  326.         edge_table[(B, A)][5] = b
  327.         if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol
  328.     else:
  329.         if has_vertex_colors(mesh):
  330.             edge_table[(A, B)] = [i, None, c, b, None, None, None, Bcol, None]
  331.         else:
  332.             edge_table[(A, B)] = [i, None, c, b, None, None, None]
  333.  
  334.     if edge_table.has_key((C, B)):
  335.         edge_table[(C, B)][1] = i
  336.         edge_table[(C, B)][4] = a
  337.         edge_table[(C, B)][5] = c
  338.         if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol
  339.     else:
  340.         if has_vertex_colors(mesh):
  341.             edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None]
  342.         else:
  343.             edge_table[(B, C)] = [i, None, a, c, None, None, None]
  344.  
  345.     if edge_table.has_key((A, C)):
  346.         edge_table[(A, C)][1] = i
  347.         edge_table[(A, C)][4] = b
  348.         edge_table[(A, C)][5] = a
  349.         if has_vertex_colors(mesh): edge_table[(A, C)][8] = Acol
  350.     else:
  351.         if has_vertex_colors(mesh):
  352.             edge_table[(C, A)] = [i, None, b, a, None, None, None, Acol, None]
  353.         else:
  354.             edge_table[(C, A)] = [i, None, b, a, None, None, None]
  355.  
  356.